const { DataTypes, Model } = require('sequelize');
const bcrypt = require('bcryptjs');
const crypto = require('crypto');
const { sequelize } = require('../config/database');

class User extends Model {
  // 验证密码
  async correctPassword(candidatePassword) {
    return await bcrypt.compare(candidatePassword, this.password);
  }

  // 检查密码是否在令牌发出后更改
  changedPasswordAfter(JWTTimestamp) {
    if (this.passwordChangedAt) {
      const changedTimestamp = parseInt(
        this.passwordChangedAt.getTime() / 1000,
        10
      );
      return JWTTimestamp < changedTimestamp;
    }
    return false;
  }

  // 创建密码重置令牌
  createPasswordResetToken() {
    const resetToken = crypto.randomBytes(32).toString('hex');
    
    this.passwordResetToken = crypto
      .createHash('sha256')
      .update(resetToken)
      .digest('hex');
    
    this.passwordResetExpires = new Date(Date.now() + 10 * 60 * 1000); // 10分钟
    
    return resetToken;
  }

  // 创建邮箱验证令牌
  createEmailVerificationToken() {
    const verificationToken = crypto.randomBytes(32).toString('hex');
    
    this.emailVerificationToken = crypto
      .createHash('sha256')
      .update(verificationToken)
      .digest('hex');
    
    this.emailVerificationExpires = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24小时
    
    return verificationToken;
  }

  // 更新最后活动时间
  async updateLastActive() {
    this.lastActive = new Date();
    return this.save({ validate: false });
  }

  // 虚拟字段: 全名
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }

  // 虚拟字段: 年龄
  get age() {
    if (!this.dateOfBirth) return null;
    const today = new Date();
    const birthDate = new Date(this.dateOfBirth);
    let age = today.getFullYear() - birthDate.getFullYear();
    const monthDiff = today.getMonth() - birthDate.getMonth();
    if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
      age--;
    }
    return age;
  }
}

User.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  // 基本信息
  username: {
    type: DataTypes.STRING(20),
    allowNull: false,
    unique: true,
    validate: {
      len: {
        args: [3, 20],
        msg: '用户名长度必须在3-20个字符之间'
      }
    }
  },
  email: {
    type: DataTypes.STRING(100),
    allowNull: false,
    unique: true,
    validate: {
      isEmail: {
        msg: '请提供有效的邮箱地址'
      }
    }
  },
  phone: {
    type: DataTypes.STRING(20),
    allowNull: false,
    unique: true,
    validate: {
      is: {
        args: /^1[3-9]\d{9}$/,
        msg: '请提供有效的手机号码'
      }
    }
  },
  password: {
    type: DataTypes.STRING(255),
    allowNull: false,
    validate: {
      len: {
        args: [8],
        msg: '密码至少需要8个字符'
      }
    }
  },
  
  // 个人信息
  firstName: {
    type: DataTypes.STRING(50),
    allowNull: false
  },
  lastName: {
    type: DataTypes.STRING(50),
    allowNull: false
  },
  avatar: {
    type: DataTypes.STRING(500),
    defaultValue: null
  },
  dateOfBirth: {
    type: DataTypes.DATE,
    validate: {
      isBeforeToday(value) {
        if (value && value >= new Date()) {
          throw new Error('出生日期不能是未来的日期');
        }
      }
    }
  },
  gender: {
    type: DataTypes.ENUM('male', 'female', 'other'),
    defaultValue: 'other'
  },
  
  // 地址信息 (JSON)
  address: {
    type: DataTypes.JSON,
    defaultValue: {}
  },
  
  // 角色和权限
  role: {
    type: DataTypes.ENUM('user', 'caregiver', 'admin'),
    defaultValue: 'user'
  },
  
  // 账户状态
  active: {
    type: DataTypes.BOOLEAN,
    defaultValue: true
  },
  emailVerified: {
    type: DataTypes.BOOLEAN,
    defaultValue: false
  },
  phoneVerified: {
    type: DataTypes.BOOLEAN,
    defaultValue: false
  },
  
  // 安全相关
  passwordChangedAt: {
    type: DataTypes.DATE
  },
  passwordResetToken: {
    type: DataTypes.STRING(255)
  },
  passwordResetExpires: {
    type: DataTypes.DATE
  },
  emailVerificationToken: {
    type: DataTypes.STRING(255)
  },
  emailVerificationExpires: {
    type: DataTypes.DATE
  },
  
  // 微信相关 (为微信小程序添加)
  wechatOpenId: {
    type: DataTypes.STRING(100),
    unique: true,
    allowNull: true,
    comment: '微信 OpenID'
  },
  wechatUnionId: {
    type: DataTypes.STRING(100),
    unique: true,
    allowNull: true,
    comment: '微信 UnionID'
  },
  wechatInfo: {
    type: DataTypes.JSON,
    defaultValue: null,
    comment: '微信用户额外信息'
  },
  
  // 偏好设置 (JSON)
  preferences: {
    type: DataTypes.JSON,
    defaultValue: {
      language: 'zh-CN',
      notifications: {
        email: true,
        sms: true,
        push: true
      },
      privacy: {
        showProfile: true,
        showLocation: false
      }
    }
  },
  
  // 统计信息 (JSON)
  stats: {
    type: DataTypes.JSON,
    defaultValue: {
      totalOrders: 0,
      completedOrders: 0,
      cancelledOrders: 0,
      rating: {
        average: 0,
        count: 0
      }
    }
  },
  
  // 最后活动时间
  lastActive: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW
  }
}, {
  sequelize,
  modelName: 'User',
  tableName: 'users',
  timestamps: true,
  indexes: [
    { fields: ['email'] },
    { fields: ['phone'] },
    { fields: ['username'] },
    { fields: ['role'] },
    { fields: ['active'] }
  ],
  defaultScope: {
    attributes: { exclude: ['password'] }
  },
  scopes: {
    withPassword: {
      attributes: {}
    },
    active: {
      where: { active: true }
    }
  },
  hooks: {
    // 密码加密
    beforeSave: async (user) => {
      if (user.changed('password')) {
        user.password = await bcrypt.hash(user.password, 12);
        
        // 设置密码修改时间
        if (!user.isNewRecord) {
          user.passwordChangedAt = new Date(Date.now() - 1000);
        }
      }
    }
  }
});

module.exports = User;